package cn.com.callback

import cn.com.elite.EliteBean;
import cn.com.elite.Util;
import cn.com.kh.getProperty;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * 常规Groovy自动任务模板TODO部分填充业务规则两者配置定时的时候有区别
 */

public class SmsBatchFailTask implements CallBackInvoke {
    private static final Logger log = LoggerFactory.getLogger(SmsBatchFailTask.class);

    public void doCallBack(EliteBean eliteBean, String callBack, Map map, String paramString) {
        // 获取数据源
        JdbcTemplate jt = new JdbcTemplate(eliteBean.getDataSource());

        // 获取内部调用安正接口地址
        String doPostIPP = getProperty.get("ccserverip"); //获取CallCenter访问地址
        String doPostURL = "http://" + doPostIPP + "/EliteGeneralHttpTask/GeneralService/SmsBatchRequest";

        // 检查是否有昨天已经调用安正但是目前还无数据的批次
        // R2表主要是控制失败重发的次数不能超过最大限制,每次发送会增加一次 默认最大3次 失败&&发送次数小于限制或还未重发
        // R3表主要是控制重发后后生成新批次,因重发生成的新的批次即使失败也不会在该功能重尝试重发
        String doSelectSQL = '''Select R1.Batch_Id, R1.Sms_Id, R1.State, Case When R2.Rec_Guid Is Null Then 0 Else R2.Deal_Times End As Deal_Times
                                  From Sms_Send_Batch R1
                                  Left Join Sys_Deal_Log R2
                                    On R1.Batch_Id = R2.Rec_Id
                                   And R2.Deal_Type = 'SmsBatchFailTask'
                                  Left Join Sys_Deal_Log R3
                                    On R1.Batch_Id = R3.Rec_Id
                                   And R3.Deal_Type = 'SmsBatchAutoTask'
                                  Left Join Sysc_Parameter Sp
                                    On 1 = 1
                                   And Sp.Parameter_Id = 'FAISMD\'
                                 Where R1.State = '0\'
                                   And ((R2.Deal_Times < R2.Limit_Times And R2.State < 1) Or R2.Rec_Guid Is Null)
                                   And R3.Rec_Guid Is Null
                                   And R1.Requesttime < Sysdate - 10 / 24
                                   And (Instr(Sp.Parametervalue, R1.Sms_Id) > 0 Or Sp.Parametervalue Is Null Or Sp.Parametervalue = '')''';
        List<Map<String, Object>> selectRes = jt.queryForList(doSelectSQL);
        log.debug("检查是否有昨天已经调用安正但是目前还无数据的批次结果:" + selectRes.toString());

        // 循环将失败的批次失败掉-并重新调用安正
        String doResult = "";
        String logState = "";
        String logComments = "";
        for (int i = 0; i < selectRes.size(); i++) {
            Map<String, Object> selectMap = selectRes.get(i);
            String doSms_ID = selectMap.get("Sms_Id").toString();
            String doBatch_ID = selectMap.get("Batch_Id").toString();
            String doState = selectMap.get("State").toString();
            int doDeal_Times = selectMap.get("Deal_Times");
            log.debug("重新调用安正批次信息Sms_Id:" + doSms_ID + " Batch_Id:" + doBatch_ID + " State:" + doState);

            try {
                // 调用发送报文
                JSONObject doPostBody = new JSONObject();
                doPostBody.put("template_id", doSms_ID);
                doPostBody.put("old_batch_id", doBatch_ID);
                doPostBody.put("requesttype", 2);
                doPostBody.put("requestdesc", "#系统自动创建(原批次超时废弃)");

                // 调用中间接口重新调用安正
                String doPostResult = Util.doHttpPost(doPostURL, doPostBody.toString(), "UTF-8", 120000, 0);

                // 处理检查返回结果
                JSONObject doResultJson = JSONObject.fromObject(doPostResult);
                int reCode = doResultJson.getInt("code");
                if (reCode == 1) {
                    logState = 1;
                    doResult = "#批次数据自动补发成功" + doResultJson.getString("msg");
                    log.debug("批次数据补发成功:" + doResultJson.getString("msg"));
                    logComments = doResult;
                } else {
                    logState = -1;
                    doResult = "#批次数据自动补发失败:" + doResultJson.getString("msg");
                    log.debug("批次数据补发失败:" + doResultJson.getString("msg"));
                    logComments = doResult;
                }

                // 如果本次调用成功或失败次数已经大于等于2次,就直接将现批次按废弃处理
                if (reCode == 1 || doDeal_Times >= 2) {
                    // 失败原有批次
                    String doFailSQL = "Update Sms_Send_Batch Set Batchstate = -3, State = 2, Comments = Comments || '--#等待安正返回数据超时，系统自动废弃重新发起#'||To_Char(Sysdate, 'yyyy-mm-dd HH24:MI:SS') Where Batch_Id = ?";
                    int doFailSQLNum = jt.update(doFailSQL, doBatch_ID);
                }

            } catch (Exception e) {
                logState = -2;
                logComments = "重新调用安正异常Sms_Id:" + doSms_ID + " Batch_Id:" + doBatch_ID + " Exception Info:" + e.getMessage();
                log.warn(logComments);

            } finally {
                // 检查批次是否有调用次数控制表
                List getLogHis = eliteBean.chaxun_sql("Select Rec_Guid, Deal_Times From Sys_Deal_Log Where Deal_Type = 'SmsBatchFailTask' And Rec_Id = '" + doBatch_ID + "'", "dataSource");
                if (getLogHis.size() <= 0) {
                    String doLogSQL = "Insert Into Sys_Deal_Log (Rec_Guid, Rec_Id, Deal_Type, Deal_Desc, Createdate, State, Comments, Deal_Times, Limit_Times) Values (Sys_Guid(), ?, 'SmsBatchFailTask', '自动将安正超时未返回批次废弃重发', Sysdate, ?, ?, 1, 3)";
                    int doLogResult = jt.update(doLogSQL, doBatch_ID, logState, logComments);
                } else {
                    String doLogSQL = "Update Sys_Deal_Log Set State = ?, Comments = ?, Deal_Times = Deal_Times + 1 Where Deal_Type = 'SmsBatchFailTask' And Rec_Id = ?";
                    int doLogResult = jt.update(doLogSQL, logState, logComments, doBatch_ID);

                }
            }
        }

        log.debug("SmsBatchFailTask对需要重试的批次操作执行结束");
    }

}
